package com.hzw.saas.service.hpc.util;

import java.math.BigDecimal;
import java.text.DecimalFormat;

/**
 * @Description: 金额工具类, 主要是金额的格式化, 金额的加、减
 * @Author: Mr.Yuan
 * @Date: 2020/2/10 10:39
 * @Version 1.0
 */
public class BigDecimalUtil {

    private BigDecimalUtil(){

    }


    private static DecimalFormat fnum = new DecimalFormat("##0.00000000");

    // 货币保留两位小数
    public static final int MONEY_POINT = 2;

    public static BigDecimal getNotNullVal(BigDecimal bigDecimal) {
        return bigDecimal == null ? BigDecimal.ZERO : bigDecimal;
    }

    public static boolean isZero(BigDecimal num) {
        return num != null && BigDecimal.ZERO.compareTo(num) == 0;
    }

    /**
     * @Description //判断两个bigdecimal是否相等
     * @param:
     * @return: 相等返回true
     * @auther: Liu Ms
     * @date: 2020/3/3 14:57
     */
    public static boolean isEquals(BigDecimal a, BigDecimal b) {
        a = a == null ? BigDecimal.ZERO : a;
        b = b == null ? BigDecimal.ZERO : b;
        return a.compareTo(b) == 0;
    }

    /**
     * 格式化金额
     *
     * @param value
     * @return
     */
    public static String formatMoney(String value) {
        if (value == null || "".equals(value)) {
            value = "0.00";
        }
        return fnum.format(new BigDecimal(value));
    }


    /**
     * 金额相加
     *
     * @param valueStr 基础值
     * @param
     * @return
     */
    public static String moneyAdd(String valueStr, String addStr) {
        BigDecimal value = new BigDecimal(valueStr);
        BigDecimal augend = new BigDecimal(addStr);
        return fnum.format(value.add(augend));
    }

    /**
     * 金额相加
     *
     * @param value      基础值
     * @param augend 被加数
     * @return
     */
    public static BigDecimal moneyAdd(BigDecimal value, BigDecimal augend) {
        return getNotNullVal(value).add(getNotNullVal(augend));
    }

    /**
     * 金额相减
     *
     * @param valueStr      基础值
     * @param minusStr 减数
     * @return
     */
    public static String moneySub(String valueStr, String minusStr) {
        BigDecimal value = new BigDecimal(valueStr);
        BigDecimal subtrahend = new BigDecimal(minusStr);
        return fnum.format(value.subtract(subtrahend));
    }

    /**
     * 金额相减
     *
     * @param value      基础值
     * @param subtrahend 减数
     * @return
     */
    public static BigDecimal moneySub(BigDecimal value, BigDecimal subtrahend) {
        return getNotNullVal(value).subtract(getNotNullVal(subtrahend));
    }


    /**
     * 金额相乘
     *
     * @param valueStr      基础值
     * @param mulStr 被乘数
     * @return
     */
    public static String moneyMul(String valueStr, String mulStr) {
        BigDecimal value = new BigDecimal(valueStr);
        BigDecimal mulValue = new BigDecimal(mulStr);
        return fnum.format(value.multiply(mulValue));
    }

    /**
     * 金额相乘
     *
     * @param value    基础值
     * @param mulValue 被乘数
     * @return
     */
    public static BigDecimal moneyMul(BigDecimal value, BigDecimal mulValue) {
        return value.multiply(mulValue);
    }

    /**
     * 金额取反
     *
     * @param value 基础值
     * @param scale 保留小数位数
     * @return
     */
    public static BigDecimal moneyNeg(BigDecimal value, Integer scale) {

        return value.negate().setScale(scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 金额相乘 保留设置小数位数(四舍五入)
     *
     * @param value    基础值
     * @param mulValue 被乘数
     * @return
     */
    public static BigDecimal moneyMulDigit(BigDecimal value, BigDecimal mulValue, int scale) {
        BigDecimal multiply = value.multiply(mulValue);
        return multiply.setScale(scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 金额相乘 <br/>
     * 精确小位小数
     * @param valueStr      基础值
     * @param divideStr 被乘数
     * @return
     */
    public static String moneydiv(String valueStr, String divideStr, int scale) {
        BigDecimal value = new BigDecimal(valueStr);
        BigDecimal divideValue = new BigDecimal(divideStr);
        return fnum.format(value.divide(divideValue, scale, BigDecimal.ROUND_HALF_UP));
    }

    /**
     * 金额相除 <br/>
     * 精确小位小数
     *
     * @param value       基础值
     * @param divideValue 被除数
     * @return
     */
    public static BigDecimal moneydiv(BigDecimal value, BigDecimal divideValue, int scale) {
        return value.divide(divideValue, scale, BigDecimal.ROUND_HALF_UP);
    }




    /**
     * 值比较大小
     * <br/>如果valueStr大于等于compValueStr,则返回true,否则返回false
     * true 代表可用余额不足
     *
     * @param valueStr     (需要消费金额)
     * @param compValueStr (可使用金额)
     * @return
     */
    public static boolean moneyComp(String valueStr, String compValueStr) {
        BigDecimal value = new BigDecimal(valueStr);
        BigDecimal compValue = new BigDecimal(compValueStr);
        //0:等于    >0:大于    <0:小于
        int result = value.compareTo(compValue);
        return result >= 0;
    }

    /**
     * 值比较大小
     * <br/>如果valueStr大于等于compValueStr,则返回true,否则返回false
     * true 代表可用余额不足
     *
     * @param valueStr     (需要消费金额)
     * @param compValueStr (可使用金额)
     * @return
     */
    public static boolean moneyComp(BigDecimal valueStr, BigDecimal compValueStr) {
        //0:等于    >0:大于    <0:小于
        valueStr = valueStr == null ? BigDecimal.ZERO : valueStr;
        compValueStr = compValueStr == null ? BigDecimal.ZERO : compValueStr;
        int result = valueStr.compareTo(compValueStr);
        return result >= 0;
    }

    /**
     * 值比较大小
     * <br/>如果valueStr等于compValueStr,则返回true,否则返回false
     * true 代表相等
     *
     * @param valueStr
     * @param compValueStr
     * @return
     */
    public static boolean moneyCompEqual(BigDecimal valueStr, BigDecimal compValueStr) {

        valueStr = valueStr == null ? BigDecimal.ZERO : valueStr;
        compValueStr = compValueStr == null ? BigDecimal.ZERO : compValueStr;
        //0:等于
        int result = valueStr.compareTo(compValueStr);
        return result == 0;
    }

    /**
     * 值比较大小
     * <br/>如果valueStr大于compValueStr,则返回true,否则返回false
     * true 代表大于0
     *
     * @param valueStr
     * @param compValueStr
     * @return
     */
    public static boolean moneyCompTh(BigDecimal valueStr, BigDecimal compValueStr) {

        valueStr = valueStr == null ? BigDecimal.ZERO : valueStr;
        compValueStr = compValueStr == null ? BigDecimal.ZERO : compValueStr;
        //0:
        int result = valueStr.compareTo(compValueStr);
        return result > 0;
    }

    /**
     * 金额乘以，省去小数点
     *
     * @param valueStr 基础值
     * @return
     */
    public static String moneyMulOfNotPoint(String valueStr, String divideStr) {
        BigDecimal value = new BigDecimal(valueStr);
        BigDecimal mulValue = new BigDecimal(divideStr);
        valueStr = fnum.format(value.multiply(mulValue));
        return fnum.format(value.multiply(mulValue)).substring(0, valueStr.length() - 3);
    }

    /**
     * 给金额加逗号切割
     *
     * @param str
     * @return
     */
    public static String addComma(String str) {
        try {
            String banNum = "";
            if (str.contains(".")) {
                String[] arr = str.split("\\.");
                if (arr.length == 2) {
                    str = arr[0];
                    banNum = "." + arr[1];
                }
            }
            // 将传进数字反转
            String reverseStr = new StringBuilder(str).reverse().toString();
            StringBuilder strTemp = new StringBuilder();
            for (int i = 0; i < reverseStr.length(); i++) {
                if (i * 3 + 3 > reverseStr.length()) {
                    strTemp.append(reverseStr.substring(i * 3));
                    break;
                }
                strTemp.append(reverseStr.substring(i * 3, i * 3 + 3)).append(",");
            }
            // 将[789,456,] 中最后一个[,]去除
            if (strTemp.toString().endsWith(",")) {
                strTemp = new StringBuilder(strTemp.substring(0, strTemp.length() - 1));
            }
            // 将数字重新反转
            return new StringBuilder(strTemp.toString()).reverse().toString() + banNum;
        } catch (Exception e) {
            return str;
        }

    }

    /**
     * @Description: 获取小数位数
     * @param
     * @return:
     * @Author: Mr.Yuan
     * @Date: 2020/2/10
     */
    public static int getNumberOfDecimalPlaces(BigDecimal bigDecimal) {
        String string = bigDecimal.stripTrailingZeros().toPlainString();
        int index = string.indexOf(".");
        return index < 0 ? 0 : string.length() - index - 1;
    }

    /**
     * 将string转成指定精度的bigdecimal
     *
     * @param desData
     * @return
     */
    public static BigDecimal stringToBigDec(String desData) {
        BigDecimal bigDecimal = new BigDecimal(desData);
        return bigDecimal.setScale(MONEY_POINT, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 讲一个string转成bigdecimal后再转成double类型
     *
     * @param v
     * @return
     */
    public static Double toExcel(String v) {
        BigDecimal bigDecimal = new BigDecimal(v);
        bigDecimal = bigDecimal.setScale(BigDecimalUtil.MONEY_POINT, BigDecimal.ROUND_HALF_UP);
        return bigDecimal.doubleValue();
    }

    /**
     * 输入一个大小 输出多少B KB MB
     */
    public static String readableFileSize(long size) {
        if (size <= 0) return "0B";
        final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"};
        int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
        return new DecimalFormat("#,##0.#").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
    }

    /**
     * 输入一个值以及区间，大于最小值，小于等于最大值
     * @param value
     * @param max
     * @param min
     * @return
     */
    public static boolean moneyCompBetween(BigDecimal value, BigDecimal max ,BigDecimal min) {
        max = max == null ? BigDecimal.ZERO : max ;
        min = min == null ? BigDecimal.ZERO : min ;
        value = value == null ? BigDecimal.ZERO : value ;

        int i = value.compareTo(max);
        int l = value.compareTo(min);
        if ( i == 0 || i <  0   &&  l > 0){
            return true;
        }
        return false ;

    }
}
